package com.demo.demothread;

import org.springframework.web.bind.annotation.Mapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.*;
import java.util.Random;

import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;

/**
 * @PackageName com.demo.demothread
 * @Description
 */
@RestController
@RequestMapping("/thread")
public class demoThread {

    public static void main(String[] args) {
        //底层实现为没有核心线程数，只有最大核心线程数，队列中只能现存1个，当等待队列进入最大核心线程时
        //可能会导致cpu100%
        ExecutorService executorService1 = Executors.newCachedThreadPool();//快
        //底层只有核心线程数，没有最大线程数，阻塞队列可以有2的31次方数量
        //线程多了对导致队列无限长，导致内存溢出，OOM
        ExecutorService executorService2 = Executors.newFixedThreadPool(10);//慢
        //线程多了对导致队列无限长，导致内存溢出，OOM
        ExecutorService executorService3 = Executors.newSingleThreadExecutor();//最慢
        //底层创建的一个类
        for (int i=1;i<100;i++){
            executorService1.execute(new MyTask(i));
        }


    }

        //自定义线程池
    public void ThreadPoolExecutor(
                                    //核心线程数
                                    int corePoolSize,
                                   //最大线程数
                                   int maximunPoolSize,
                                   //过期时间
                                   TimeUnit unit,
                                   //阻塞队列
                                   BlockingDeque<Runnable> workQueue,
                                   //线程工厂
                                   ThreadFactory threadFactory,
                                   //拒绝策略
                                   RejectedExecutionHandler rejectedExecutionHandler){
        if (corePoolSize>0){
            System.out.println("finish");
        }
    }

    /**
     * 定义线程池，用于所有异步任务处理
     */
    public final ThreadPoolExecutor executor = new ThreadPoolExecutor(
            5, 60, 300, TimeUnit.SECONDS,
            new LinkedBlockingDeque<>(20000),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy()
    );

    public void threadTest1() {
        //可以通过下面的代码来获取当前计算机的CPU的核数。
        int processors = Runtime.getRuntime().availableProcessors();

        // 第一种线程池:固定个数的线程池,可以为每个CPU核绑定一定数量的线程数
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(processors * 4);
        for (int i = 0; i < 10; i++) {
            fixedThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                }
            });
        }
    }

    //自己定制线程池
    class MyAppThread extends Thread {

        private static final String DEFAULT_NAME = "TomDog";

        private static volatile boolean debugLifeCycle = true;

        private static final AtomicInteger created = new AtomicInteger();

        private static final AtomicInteger alive = new AtomicInteger();

        private static final Logger log = Logger.getAnonymousLogger();

        public MyAppThread(Runnable runnable) {

            this(runnable, DEFAULT_NAME);

        }

        public MyAppThread(Runnable runnable, String name) {

            super(runnable, name + "-" + created.incrementAndGet());

            setUncaughtExceptionHandler(
                    new Thread.UncaughtExceptionHandler() {
                        public void uncaughtException(Thread t, Throwable e) {
                            System.out.println("UNCAUGHT in thread " + t.getName());

                        }
                    }
            );
        }

        @Override
        public void run() {
            boolean debug = debugLifeCycle;
            if (debug) {
                System.out.println("Created " + getName());
            }
            try {
                alive.decrementAndGet();
                super.run();
            } finally {
                alive.decrementAndGet();
                if (debug) {
                    System.out.println("Exiting " + getName());
                }
            }
        }
    }
}


